﻿#ifndef TETRISBOARD_H
#define TETRISBOARD_H

#include <QFrame>
#include <QWidget>
#include <QTimer>
#include <QPointer>
#include <QPainter>
#include <QTimerEvent>
#include <QKeyEvent>

#include "tetrispiece.h"

class TetrisBoard : public QFrame
{
    Q_OBJECT
public:
    TetrisBoard(QWidget *parent = nullptr);

    void start();
    void pause();
    bool isPaused() const { return isPausedState; }
    bool isGameOver() const { return isGameOverState; }
    const TetrisPiece& getNextPiece() const { return nextPiece; }

public slots:
    void dropDown();
    void oneLineDown();
    void pieceMoved();
    void pieceDropped();
    void rotateLeft();
    void rotateRight();
    void moveLeft();
    void moveRight();

signals:
    void scoreChanged(int score);
    void levelChanged(int level);
    void linesRemovedChanged(int count);
    void gameOver();
    void nextPieceChanged();

protected:
    void paintEvent(QPaintEvent *event) override;
    void keyPressEvent(QKeyEvent *event) override;
    void timerEvent(QTimerEvent *event) override;

private:
    enum { BoardWidth = 10, BoardHeight = 22 };

    int squareWidth() const { return contentsRect().width() / BoardWidth; }
    int squareHeight() const { return contentsRect().height() / BoardHeight; }
    void clearBoard();
    void drawSquare(QPainter &painter, int x, int y, TetrisPiece::PieceShape shape);
    void newPiece();
    bool tryMove(const TetrisPiece &newPiece, int newX, int newY);
    void removeFullLines();
    TetrisPiece::PieceShape shapeAt(int x, int y) const;
    void setShapeAt(int x, int y, TetrisPiece::PieceShape shape);
    int timeoutTime() const;

    QTimer timer;
    TetrisPiece curPiece;
    TetrisPiece nextPiece;
    bool isStarted;
    bool isPausedState;
    bool isGameOverState;
    int curX;
    int curY;
    int numLinesRemoved;
    int numPiecesDropped;
    int score;
    int level;
    TetrisPiece::PieceShape board[BoardHeight][BoardWidth];
};

#endif // TETRISBOARD_H
